- /* sdfsinrn.cpp by K.Tsuru */
- // function ID 3206 DRADIX
- /**********************************************************************************
- SDouble class
- sin x for |x| < pi/4
- x/(R^N) reducing method
- It is convenient to take R=5, because 1/(R^N) is a finite decimal fraction in
- DRADIX.
- [Algorithm]
- We use a formula
- sin(5x) = 16*sin(x)^5 - 20*sin(x)^3 + 5*sin(x).
- step 1 :Taking R=5 the value d = x/(R^n)(n integer) is evaluated.
- step 2 :We get y(n) = sin d by series.
- step 3 :While n > 0 we repeat
- y(n-1) <-- 16*y(n)^5 - 20*y(n)^3 + 5*y(n), n <-- n-1.
- It is better to change the value of 'n' depending the number of effective figures.
- **********************************************************************************/
- #ifndef SN_H
- #include "sn.h"
- #endif
- SDouble SinRN(const SDouble& x){ // |x| <= pi/4
- int k;
- const uint R = 5u;
- const double logR = log10((double)R); // ver. 2.17
- uint effFig = x.EffFig(), upPrec;
- double pw = log10((double)effFig);
- const int n = int(0.5*DFIGURES*pw*pw) + x.RdxExp();
-
- if(n <= 0) return SinSeries(x); // enough small
- // n > 0
- k = int( (double)n*logR )+ 1; //the number of figures of R^n
- upPrec = k/DFIGURES + 1u; //temporally raising up precision
- if(k % DFIGURES) upPrec++;
-
- RealSize C;
- SDouble u, y;
- uint up = x.ProperUpPrec(upPrec);
- //It temporally raises up the precision if possible.
- if(up) C.SetEffFig(effFig + up, C.TEMP_EXTEND);
- u = x/Dpow(R, n); // u = x/(R^n)
- y = SinSeries(u); //SinSeries(u); // sin(x/(5^n))
- k = n;
- x.iterationCount = n;
- // y(n-1) = 16*y(n)^5 - 20*y(n)^3 + 5*y(n), n <-- n-1
- while(k > 0){
- u = DsMult(y, 2); // u = 2y
- u *= u; // u = 4*y^2
- u = u*u - DsMult(u-ONE, 5); // 16*y^4 -5*(4*y^2 -1)
- y = u*y;
- k--;
- }
- if(up){
- C.SetEffFig(0);
- y.Reform(3206);
- }
- return y;
- }
sdfsinrn.cpp : last modifiled at 2017/09/07 15:09:42(1,844 bytes)
created at 2017/10/07 10:22:50
The creation time of this html file is 2017/10/07 11:29:39 (Sat Oct 07 11:29:39 2017).